// go语言内置容器
package main

// func main() {
// 	// var student [3]string	// 申明数组
// 	var student = [...]string{"Tom", "Ben", "Peter"}
// 	fmt.Println(student)
// }

// range 关键字
// func main() {
// 	var num = [...]int{1, 2, 3, 4}
// 	for k, v := range num {
// 		fmt.Println("变量k:", k, "变量v:", v)
// 	}
// }

// 切片
// func main() {
// 	var student = [...]string{"Tom", "Ben", "Peter", "Zero"}
// 	var student1 = student[1:3]
// 	var student2 = student1[:1]
// 	fmt.Println("student数组:", student)
// 	fmt.Println("student1切片:", student1)
// 	fmt.Println("student数组地址为:", &student[0])
// 	fmt.Println("student数组[1]地址为:", &student[1])
// 	fmt.Println("student1切片地址为:", &student1[0])
// 	fmt.Println("student1切片长度为:", len(student1))
// 	fmt.Println("student1切片容量为:", cap(student1))
// 	fmt.Println("student2切片地址为:", &student2[0])
// 	fmt.Println("student2切片长度为:", len(student2))
// 	fmt.Println("student2切片容量为:", cap(student2))
// }

// 直接生成一个新切片
// func main() {
// 	// var student []int            // 切片申明
// 	// student = make([]int, 2, 10) // make 初始化   make([]元素类型, 切片长度, 切片容量)
// 	// var student = []string{"Tom", "Peter", "Ben"} // 切片申明并初始化
// 	// fmt.Println("student切片 :", student)
// 	// fmt.Println("student切片长度:", len(student))
// 	// fmt.Println("student切片容量", cap(student))
// 	// fmt.Println("判定student切片是否为空：", student == nil) // 切片申明后内容长度容量为空
// 	student := [...]string{"Tom", "Peter", "Ben"}
// 	// var student1 = student[1:2]       // 值引用  操作时会对原数组造成影响
// 	student1 := make([]string, 1, 1)
// 	copy(student1, student[1:2]) // 值复制  操作时不会对原数组造成影响
// 	fmt.Println("student数组:", student)
// 	fmt.Println("student1切片:", student1)
// 	fmt.Println("student数组地址:", &student[0])
// 	fmt.Println("student1切片地址:", &student1[0])
// 	student1 = append(student1, "Zero")
// 	student1 = append(student1, "Zero2")
// 	fmt.Println("扩充Zero后student1切片:", student1, "切片长度为:", len(student1), "切片容量为:", cap(student1))
// 	fmt.Println("扩充Zero后student数组:", student)
// }

// 切片删除元素 go没有提供删除切片元素的方法，需要自定义截取拼接
// func main() {
// 	var student = []string{"Tom", "Ben", "Peter", "Danny"}
// 	fmt.Println("student切片", student)
// 	// student = append(student[:1], student[2:]) // 不支持类型
// 	student = append(student[:1], student[2:]...)
// 	// 删除所有元素
// 	// student = student[0:0]
// 	fmt.Println("student切片长度:", len(student))
// 	fmt.Println("student切片容量:", cap(student))
// 	fmt.Println("student切片:", student)
// 	// 遍历切片
// 	for k, v := range student {
// 		fmt.Println("切片下标:", k, "对应元素:", v)
// 	}

// }

// map 映射
// 映射是一种无序的键值对集合
// func main() {
// 	var studentScoreMap map[string]int
// 	fmt.Println(studentScoreMap)
// }
// 初始化
// func main() {
// 	// 申明同时初始化
// 	// var studentScoreMap = map[string]int{
// 	// 	"Tom":   80,
// 	// 	"Ben":   85,
// 	// 	"Peter": 90,
// 	// }
// 	var studentScoreMap map[string]int
// 	// 使用make函数初始化， 可以不指定容量， 但是对于map的多次扩充会造成性能损耗
// 	studentScoreMap = make(map[string]int)
// 	studentScoreMap["Tom"] = 80
// 	studentScoreMap["Ben"] = 85
// 	studentScoreMap["Peter"] = 90

// 	fmt.Println(studentScoreMap)
// 	// fmt.Println("studentScoreMap长度为:", len(studentScoreMap))
// 	// fmt.Println("studentScoreMap容量为:", cap(studentScoreMap))  cap方法只支持切片
// 	// 遍历映射
// 	// for k, v := range studentScoreMap {
// 	// 	fmt.Println(k, v)
// 	// }
// 	// for k := range studentScoreMap {
// 	// 	fmt.Println(k)
// 	// }
// 	// for _, v := range studentScoreMap {
// 	// 	fmt.Println(v)
// 	// }

// 	// 从映射中删除键值对 delete(map, key)
// 	// delete(studentScoreMap, "Tom")
// 	// delete(studentScoreMap, "check")
// 	// fmt.Println(studentScoreMap)
// 	// go map 没有清空方法 只能重新定义
// 	studentScoreMap = map[string]int{}
// 	fmt.Println(studentScoreMap)
// }

// 并发操作map
// import (
// 	"fmt"
// 	"sync"
// )

// func readMap(GoMap map[int]int, key int) int {
// 	// return GoMap[key] // 无锁测试
// 	lock.Lock()
// 	m := GoMap[key]
// 	lock.Unlock()
// 	return m

// }

// func writeMap(GoMap map[int]int, key int, value int) {
// 	// GoMap[key] = value  // 无锁测试

// 	lock.Lock()
// 	GoMap[key] = value
// 	lock.Unlock()
// }

// var lock sync.RWMutex

// func main() {
// 	GoMap := make(map[int]int)
// 	for i := 0; i < 10000; i++ {
// 		go writeMap(GoMap, i, i)
// 		go readMap(GoMap, i)
// 	}
// 	fmt.Println("done")
// }

// 并发操作map  使用效率较高的并发安全map sync.Map
// sync.Map 特点  内部通过冗余数据结构降低加锁对性能影响、
// 使用直接申明 无需初始化
// 读取和赋值操作与map不同
import (
	"fmt"
	"sync"
)

func readMapSlock(GoMap sync.Map, key int) int {
	res, ok := GoMap.Load(key)
	if ok == true {
		return res.(int)
	} else {
		return 0
	}

}

func writeMapSlock(GoMap sync.Map, key int, value int) {
	GoMap.Store(key, value)
}

var lock sync.RWMutex

func main() {
	var GoMap sync.Map
	for i := 0; i < 10000; i++ {
		go writeMapSlock(GoMap, i, i)
		go readMapSlock(GoMap, i)
	}
	fmt.Println("done")
	// fmt.Println("GoMap容量为:", len(GoMap))  // 不支持 len
}
